package com.example.statistics.utils

import android.app.Activity
import android.content.Intent
import android.os.Bundle
import android.os.Parcelable
import androidx.fragment.app.FragmentActivity
import org.jetbrains.anko.AnkoException
import java.io.Serializable

inline fun <reified T> FragmentActivity.activityForResult(vararg params: Pair<String, Any?>, noinline body: (Intent?) -> Unit) {
    val fragmentManager = this.supportFragmentManager
    val tag = javaClass.name
    var fragment: OnResultFragment? = fragmentManager.findFragmentByTag(tag) as OnResultFragment?

    try {
        if (fragment == null) {
            fragment = OnResultFragment()
            fragmentManager
                    .beginTransaction()
                    .add(fragment, tag)
                    .commitAllowingStateLoss()
            fragmentManager.executePendingTransactions()
        }
        val intent = Intent(this, T::class.java)

        if (params.isNotEmpty()) intent.fillIntentArguments(params)
        fragment.startActivityForResult(intent, body)
    } catch (e: Exception) {
        e.printStackTrace()
    }
}

fun FragmentActivity.activityForResult(intent: Intent, vararg params: Pair<String, Any?>, body: (Intent?) -> Unit) {
    val fragmentManager = this.supportFragmentManager
    val tag = javaClass.name
    var fragment: OnResultFragment? = fragmentManager.findFragmentByTag(tag) as OnResultFragment?

    try {
        if (fragment == null) {
            fragment = OnResultFragment()
            fragmentManager
                    .beginTransaction()
                    .add(fragment, tag)
                    .commitAllowingStateLoss()
            fragmentManager.executePendingTransactions()
        }
        if (params.isNotEmpty()) intent.fillIntentArguments(params)
        fragment.startActivityForResult(intent, body)
    } catch (e: Exception) {
        e.printStackTrace()
    }
}

fun FragmentActivity.activityFinish(vararg params: Pair<String, Any?>) {
    val intent = Intent()
    if (params.isNotEmpty()) intent.fillIntentArguments(params)
    setResult(Activity.RESULT_OK, intent)
    finish()
}


fun Intent.fillIntentArguments(params: Array<out Pair<String, Any?>>) {
    params.forEach {
        val value = it.second
        when (value) {
            null -> this.putExtra(it.first, null as Serializable?)
            is Int -> this.putExtra(it.first, value)
            is Long -> this.putExtra(it.first, value)
            is CharSequence -> this.putExtra(it.first, value)
            is String -> this.putExtra(it.first, value)
            is Float -> this.putExtra(it.first, value)
            is Double -> this.putExtra(it.first, value)
            is Char -> this.putExtra(it.first, value)
            is Short -> this.putExtra(it.first, value)
            is Boolean -> this.putExtra(it.first, value)
            is Serializable -> this.putExtra(it.first, value)
            is Bundle -> this.putExtra(it.first, value)
            is Parcelable -> this.putExtra(it.first, value)
            is Array<*> -> when {
                value.isArrayOf<CharSequence>() -> this.putExtra(it.first, value)
                value.isArrayOf<String>() -> this.putExtra(it.first, value)
                value.isArrayOf<Parcelable>() -> this.putExtra(it.first, value)
                else -> throw AnkoException("this extra ${it.first} has wrong type ${value.javaClass.name}")
            }
            is IntArray -> this.putExtra(it.first, value)
            is LongArray -> this.putExtra(it.first, value)
            is FloatArray -> this.putExtra(it.first, value)
            is DoubleArray -> this.putExtra(it.first, value)
            is CharArray -> this.putExtra(it.first, value)
            is ShortArray -> this.putExtra(it.first, value)
            is BooleanArray -> this.putExtra(it.first, value)
            else -> throw AnkoException("Intent extra ${it.first} has wrong type ${value.javaClass.name}")
        }
        return@forEach
    }
}
